this._matchedItems = [];
// map<itemId, GenericDisplayItem>
this._displayedItems = {};
- this._displayedItemsCount = 0;
this._selectedIndex = -1;
// These two are public - .actor is the normal "actor subclass" property,
// but we also expose a .displayControl actor which is separate.
// to the bottom one. Returns true if the selection actually moved up, false if it wrapped
// around to the bottom.
selectUp: function() {
+ let count = this._list.displayedCount;
let selectedUp = true;
let prev = this._selectedIndex - 1;
if (this._selectedIndex <= 0) {
- prev = this._displayedItemsCount - 1;
+ prev = count - 1;
selectedUp = false;
}
this._selectIndex(prev);
// to the top one. Returns true if the selection actually moved down, false if it wrapped
// around to the top.
selectDown: function() {
+ let count = this._list.displayedCount;
let selectedDown = true;
let next = this._selectedIndex + 1;
- if (this._selectedIndex == this._displayedItemsCount - 1) {
+ if (this._selectedIndex == count - 1) {
next = 0;
selectedDown = false;
}
// Selects the last item among the displayed items.
selectLastItem: function() {
+ let count = this._list.displayedCount;
if (this.hasItems())
- this._selectIndex(this._displayedItemsCount - 1);
+ this._selectIndex(count - 1);
},
// Returns true if the display has some item selected.
// Returns true if the display has any displayed items.
hasItems: function() {
- return this._displayedItemsCount > 0;
+ return this._list.displayedCount > 0;
},
// Updates the displayed items and makes the display actor visible.
}));
this._list.add_actor(displayItem.actor);
this._displayedItems[itemId] = displayItem;
- this._displayedItemsCount++;
},
// Removes an item identifed by the itemId from the displayed items.
_removeDisplayItem: function(itemId) {
+ let count = this._list.displayedCount;
let displayItem = this._displayedItems[itemId];
let displayItemIndex = this._getIndexOfDisplayedActor(displayItem.actor);
- if (this.hasSelected() && (this._displayedItemsCount == 1 || !this._list.visible)) {
+ if (this.hasSelected() && (count == 1 || !this._list.visible)) {
this.unsetSelected();
} else if (this.hasSelected() && displayItemIndex < this._selectedIndex) {
this.selectUp();
displayItem.destroy();
delete this._displayedItems[itemId];
- this._displayedItemsCount--;
},
// Removes all displayed items.
*/
_updateDisplayControl: function(resetDisplayControl) {
if (resetDisplayControl) {
+ this._selectedIndex = -1;
this.displayControl.remove_all();
let nPages = this._list.n_pages;
let pageNumber = this._list.page;
// Returns a display item based on its index in the ordering of the
// display children.
_findDisplayedByIndex: function(index) {
- let displayedActors = this._list.get_children();
- let actor = displayedActors[index];
+ let actor = this._list.get_displayed_actor(index);
return this._findDisplayedByActor(actor);
},
// Selects (e.g. highlights) a display item at the provided index,
// updates this.selectedItemDetails actor, and emits 'selected' signal.
_selectIndex: function(index) {
- if (this._selectedIndex != -1) {
+ let count = this._list.displayedCount;
+ if (this._selectedIndex >= 0) {
let prev = this._findDisplayedByIndex(this._selectedIndex);
prev.markSelected(false);
// Calling destroy() gets large image previews released as quickly as
this.selectedItemDetails.remove_all();
}
- this._selectedIndex = index;
- if (index != -1 && index < this._displayedItemsCount) {
- let item = this._findDisplayedByIndex(index);
- item.markSelected(true);
- this.selectedItemDetails.append(item.createDetailsActor(this._availableWidthForItemDetails, this._availableHeightForItemDetails), Big.BoxPackFlags.NONE);
- this.emit('selected');
+ if (index < count) {
+ this._selectedIndex = index;
+ if (index >= 0) {
+ let item = this._findDisplayedByIndex(index);
+ item.markSelected(true);
+ this.selectedItemDetails.append(item.createDetailsActor(this._availableWidthForItemDetails,
+ this._availableHeightForItemDetails), Big.BoxPackFlags.NONE);
+ this.emit('selected');
+ }
}
}
};
me.emit('activated');
return true;
} else if (symbol == Clutter.Up) {
+ if (!me._resultsShowing())
+ return true;
// selectUp and selectDown wrap around in their respective displays
// too, but there doesn't seem to be any flickering if we first select
// something in one display, but then unset the selection, and move
me._resultsAppsSection.display.selectUp();
else
me._resultsDocsSection.display.selectUp();
+ return true;
} else if (symbol == Clutter.Down) {
+ if (!me._resultsShowing())
+ return true;
if (me._resultsDocsSection.display.hasSelected())
me._resultsDocsSection.display.selectDown();
else if (me._resultsAppsSection.display.hasItems())
me._resultsAppsSection.display.selectDown();
else
me._resultsDocsSection.display.selectDown();
+ return true;
}
return false;
});
PROP_0,
PROP_SPACING,
PROP_ITEM_HEIGHT,
+ PROP_DISPLAYED_COUNT,
PROP_PAGE,
PROP_N_PAGES
};
guint page;
guint n_pages;
guint items_per_page;
+ guint displayed_count;
};
+static void
+recalc_displayed_count (ShellOverflowList *self)
+{
+ GList *children;
+ int n_children;
+ int displayed_count;
+ int page, n_pages;
+
+ children = clutter_container_get_children (CLUTTER_CONTAINER (self));
+ n_children = g_list_length (children);
+ g_list_free (children);
+
+ page = self->priv->page;
+ n_pages = self->priv->n_pages;
+ if (page < n_pages-1)
+ displayed_count = self->priv->items_per_page;
+ else if (n_pages > 0)
+ displayed_count = n_children - (self->priv->items_per_page * (n_pages-1));
+ else
+ displayed_count = 0;
+ if (displayed_count != self->priv->displayed_count)
+ {
+ self->priv->displayed_count = displayed_count;
+ g_object_notify (G_OBJECT (self), "displayed-count");
+ }
+}
+
static void
shell_overflow_list_set_property(GObject *object,
guint prop_id,
break;
case PROP_PAGE:
priv->page = g_value_get_uint (value);
+ recalc_displayed_count (self);
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
break;
default:
case PROP_ITEM_HEIGHT:
g_value_set_float (value, priv->spacing);
break;
+ case PROP_DISPLAYED_COUNT:
+ g_value_set_uint (value, priv->displayed_count);
+ break;
case PROP_PAGE:
g_value_set_uint (value, priv->page);
break;
}
priv->items_per_page = n_fits;
+
if (n_pages != priv->n_pages)
{
priv->n_pages = n_pages;
g_object_notify (G_OBJECT (self), "n-pages");
}
+ recalc_displayed_count (self);
+
g_list_free (children);
}
shell_overflow_list_pick (ClutterActor *actor,
const ClutterColor *color)
{
- ShellOverflowList *self = SHELL_OVERFLOW_LIST (actor);
- ShellOverflowListPrivate *priv = self->priv;
- GList *children, *iter;
- int i;
-
(CLUTTER_ACTOR_CLASS (g_type_class_peek (clutter_actor_get_type ())))->pick (actor, color);
- shell_overflow_list_paint (self);
+ shell_overflow_list_paint (actor);
}
0.0, G_MAXFLOAT, 0.0,
G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_DISPLAYED_COUNT,
+ g_param_spec_uint ("displayed-count",
+ "Displayed count",
+ "Number of items displayed on current page",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE));
+
g_object_class_install_property (gobject_class,
PROP_PAGE,
g_param_spec_uint ("page",
PROP_N_PAGES,
g_param_spec_uint ("n-pages",
"Number of pages",
- "Number of pagest",
+ "Number of pages",
0, G_MAXUINT, 0,
G_PARAM_READABLE));
self->priv->n_pages = 1;
self->priv->page = 0;
}
+
+/**
+ * shell_overflow_list_get_displayed_actor:
+ * @self:
+ * @index: 0-based index for displayed list
+ *
+ * Returns the actor at the given index on the current page.
+ *
+ * Return value: (transfer none): #ClutterActor at index
+ */
+ClutterActor *
+shell_overflow_list_get_displayed_actor (ShellOverflowList *self,
+ guint index)
+{
+ GList *children, *iter;
+
+ children = clutter_container_get_children (CLUTTER_CONTAINER (self));
+
+ if (children == NULL)
+ return NULL;
+
+ iter = g_list_nth (children, index + (self->priv->page * self->priv->items_per_page));
+
+ if (!iter)
+ return NULL;
+
+ return iter->data;
+}